#include "fb.h"

//---------------------------------------------------------------------------
/*
 * open framebuffer device.
 * return positive file descriptor if success,
 * else return -1.
 */
int fb_open(char *fb_device)
{
  int  fd;
  if ((fd = open(fb_device, O_RDWR)) < 0) {
    perror(__func__);
    return (-1);
  }
  return (fd);
}
//---------------------------------------------------------------------------
/*
 * get framebuffer's width,height,and depth.
 * return 0 if success, else return -1.
 */
int fb_stat(int fd, int *width, int *height, int *depth)
{
  struct fb_fix_screeninfo fb_finfo;
  struct fb_var_screeninfo fb_vinfo;
  int fbn =0;

  if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
    perror(__func__);
    return (-1);
  }

  if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
    perror(__func__);
    return (-1);
  }

#if 0
  //init to 0
  if (ioctl(fd,FLCD_SET_FB_NUM,&fbn)<0) {
    printf("Fail to set fb num\n");
    return 0;
  }


  if (ioctl(fd,FLCD_GET_DATA_SEP, &f_data) < 0) {
    printf("LCD Error: can not operate 0x%x\n", FLCD_GET_DATA_SEP);
    return 0;
  }

  fb_uvoffset = f_data.uv_offset;
  #ifdef _DEBUG
    printf("f_data.uv_offset = %d\n", fb_uvoffset);
  #endif
#endif    
  *width = fb_vinfo.xres;
  *height = fb_vinfo.yres;
  *depth = fb_vinfo.bits_per_pixel;
  return (0);
}
//---------------------------------------------------------------------------
//设置显存页
int fb_setpage(int fd, int fbn)
{
#if 0
  //init to 0
  if (ioctl(fd,FLCD_SET_FB_NUM,&fbn)<0) {
    printf("Fail to set fb num\n");
    return 0;
  }
#endif  
}
//---------------------------------------------------------------------------
//打开显示
int fb_display_open(int fd)
{
#if 0
  if (ioctl(fd, FLCD_OPEN, NULL)) {
    perror(__func__);
    return (-1);
  }
#endif  
  return (0);
}
//---------------------------------------------------------------------------
//关闭显示
int fb_display_close(int fd)
{
#if 0
  if (ioctl(fd, FLCD_CLOSE, NULL)) {
    perror(__func__);
    return (-1);
  }
#endif  
  return (0);
}
//---------------------------------------------------------------------------
/*
 * map shared memory to framebuffer device.
 * return maped memory if success,
 * else return -1, as mmap dose.
 */
void *fb_mmap(int fd, unsigned int screensize)
{
  caddr_t fbmem;
  if ((fbmem = mmap(0, screensize, PROT_READ | PROT_WRITE,
      MAP_SHARED, fd, 0)) == MAP_FAILED) {
        perror(__func__);
        return (void *) (-1);
  }
  return (fbmem);
}
//---------------------------------------------------------------------------
/*
 * unmap map memory for framebuffer device.
 */
int fb_munmap(void *start, size_t length)
{
	return (munmap(start, length));
}
//---------------------------------------------------------------------------
/*
 * close framebuffer device
 */
int fb_close(int fd)
{
	return (close(fd));
}
//---------------------------------------------------------------------------
/*
 * display a pixel on the framebuffer device.
 * fbmem is the starting memory of framebuffer,
 * width and height are dimension of framebuffer,
 * x and y are the coordinates to display,
 * color is the pixel's color value.
 * return 0 if success, otherwise return -1.
 */

int fb_pixel(/*unsigned char *fbmem, */int width, int height,
		 int x, int y, unsigned short color, int PageNo)
{
#if 0
  uint8_t isU;
  uint8_t isChr;

  uint8_t Y;
  uint8_t U;
  uint8_t V;

  if ((x > width) || (y > height))
    return (-1);

  isU=0;
  if( y%2==0 ) isU=1; // this is a U line

  switch(color)
   {
    case cWhite:  //  1
               Y=235;
               U=128;
               V=128;
               break;
    case cYellow: // 2
               Y=210;
               U=16;
               V=146;
               break;
    case cCyan:   //   3
               Y=170;
               U=166;
               V=16;
               break;
    case cGreen:  //  4
               Y=145;
               U=54;
               V=34;
               break;
    case cMagenta://  5
               Y=106;
               U=202;
               V=222;
               break;
    case cRed:    //  6
               Y=81;
               U=90;
               V=240;
               break;
    case cBlue:   //  7
               Y=41;
               U=240;
               V=110;
               break;
    case cBlack:  //  8
               Y=16;
               U=128;
               V=128;
               break;
    default:
               Y=16;
               U=128;
               V=128;
               break;
   }
  *(fbmem + f_data.buf_len*PageNo + y*width + x) = Y;
/*  isChr = 0;
  if( x%2==0 )
    isChr=1;
  if( (isChr==1) && (isU==1) )
    *(fbmem + f_data.uv_offset + (y/2*width)/2 +x/2) = U;
  if( (isChr==1)&& (isU !=1))
    *(fbmem + f_data.uv_offset+f_data.uv_offset/4 + (y/2*width)/2 +x/2) = V;   */
#endif
  return (0);
}
//---------------------------------------------------------------------------
void fb_line(int start_x,int start_y,int end_x,int end_y, unsigned short color, int PageNo)
{
#if 0
  int i,j;
  for(j=start_y;j<=end_y;j++)
    for(i=start_x;i<=end_x;i++)
     {
      fb_pixel(fb_width, fb_height, i, j, color, PageNo);
     }
#endif
}
